#!/bin/bash

# Holter Build Wizard Script
# A comprehensive build script that handles all aspects of the Holter system
# Supports both development (no sudo) and production (with sudo) modes

set -euo pipefail

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HOLTER_DIR="$SCRIPT_DIR"
LOG_FILE="/tmp/holter-build-wizard.log"
DB_PATH="$HOLTER_DIR/monitor/data/monitor.db"
MIGRATION_SCRIPT="$HOLTER_DIR/migrate_to_trodes.sql"

# Mode detection and configuration
DEV_MODE=false
if [[ $# -gt 0 ]] && ([[ "$1" == "--dev" ]] || [[ "$1" == "-d" ]]); then
    DEV_MODE=true
    shift
fi

# Development paths (no sudo required)
if [[ "$DEV_MODE" == "true" ]]; then
    WEB_ROOT="$HOLTER_DIR/web"
    NGINX_CONFIG_DIR="$HOLTER_DIR/nginx"
    NGINX_CONFIG="$NGINX_CONFIG_DIR/holter.conf"
    TOTAL_STEPS=7
else
    # Production paths (sudo required)
    WEB_ROOT="/var/www/holter"
    NGINX_CONFIG_DIR="/etc/nginx"
    NGINX_SITES_DIR="/etc/nginx/sites-available"
    NGINX_CONFIG="$NGINX_SITES_DIR/holter"
    TOTAL_STEPS=8
fi

# Progress tracking
CURRENT_STEP=0

# Logging functions
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1" | tee -a "$LOG_FILE"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1" | tee -a "$LOG_FILE"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1" | tee -a "$LOG_FILE"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1" | tee -a "$LOG_FILE"
}

log_step() {
    CURRENT_STEP=$((CURRENT_STEP + 1))
    echo -e "${PURPLE}[STEP $CURRENT_STEP/$TOTAL_STEPS]${NC} $1" | tee -a "$LOG_FILE"
}

log_progress() {
    echo -e "${CYAN}[PROGRESS]${NC} $1" | tee -a "$LOG_FILE"
}

# Help function
show_help() {
    cat << EOF
Holter Build Wizard Script

This script performs a complete build and setup of the Holter monitoring system.
Supports both development (no sudo) and production (with sudo) modes.

Usage: $0 [MODE] [OPTIONS]

Modes:
    --dev, -d                    Development mode (no sudo required)
    (no mode)                    Production mode (sudo required)

Options:
    -h, --help                   Show this help message
    -v, --verbose                Enable verbose output
    --skip-db-reset             Skip database reinitialization

    --skip-frontend             Skip frontend build
    --log-file FILE             Specify log file (default: $LOG_FILE)
    --web-root DIR              Web root directory
    --nginx-config FILE         Nginx config file

Development Mode Examples:
    $0 --dev                     # Full development build
    $0 --dev --skip-db-reset     # Build without resetting database
    $0 --dev --verbose           # Verbose output

Production Mode Examples:
    $0                           # Full production build
    $0 --skip-db-reset           # Build without resetting database

    $0 --verbose                 # Verbose output

EOF
}

# Parse command line arguments
SKIP_DB_RESET=false
SKIP_FRONTEND=false
VERBOSE=false

while [[ $# -gt 0 ]]; do
    case $1 in
        -h|--help)
            show_help
            exit 0
            ;;
        -v|--verbose)
            VERBOSE=true
            shift
            ;;
        --skip-db-reset)
            SKIP_DB_RESET=true
            shift
            ;;

        --skip-frontend)
            SKIP_FRONTEND=true
            shift
            ;;
        --log-file)
            LOG_FILE="$2"
            shift 2
            ;;
        --web-root)
            WEB_ROOT="$2"
            shift 2
            ;;
        --nginx-config)
            NGINX_CONFIG="$2"
            shift 2
            ;;
        *)
            log_error "Unknown option: $1"
            show_help
            exit 1
            ;;
    esac
done

# Initialize log file
echo "=== Holter Build Wizard Log ===" > "$LOG_FILE"
echo "Started at: $(date)" >> "$LOG_FILE"
echo "Mode: $([ "$DEV_MODE" == "true" ] && echo "Development" || echo "Production")" >> "$LOG_FILE"
echo "Arguments: $*" >> "$LOG_FILE"
echo "" >> "$LOG_FILE"

# Function to check if command exists
command_exists() {
    command -v "$1" >/dev/null 2>&1
}

# Function to check prerequisites
check_prerequisites() {
    log_step "Checking prerequisites..."
    
    local missing_tools=()
    
    # Check Go
    if ! command_exists go; then
        missing_tools+=("Go (https://golang.org/doc/install)")
    else
        local go_version=$(go version | awk '{print $3}')
        log_progress "Go found: $go_version"
    fi
    
    # Check Node.js
    if ! command_exists node; then
        missing_tools+=("Node.js (https://nodejs.org/)")
    else
        local node_version=$(node --version)
        log_progress "Node.js found: $node_version"
    fi
    
    # Check npm
    if ! command_exists npm; then
        missing_tools+=("npm (comes with Node.js)")
    else
        local npm_version=$(npm --version)
        log_progress "npm found: $npm_version"
    fi
    
    # Check sqlite3
    if ! command_exists sqlite3; then
        missing_tools+=("sqlite3 (sudo apt-get install sqlite3)")
    else
        log_progress "sqlite3 found"
    fi
    
    # Check git
    if ! command_exists git; then
        missing_tools+=("git (sudo apt-get install git)")
    else
        log_progress "git found"
    fi
    
    # Check nginx (mandatory for production mode)
    if [[ "$DEV_MODE" == "false" ]]; then
        if ! command_exists nginx; then
            log_warning "nginx not found. Will provide installation instructions."
            echo ""
            echo "To install nginx:"
            echo "  Ubuntu/Debian: sudo apt-get install nginx"
            echo "  CentOS/RHEL:   sudo yum install nginx"
            echo "  macOS:         brew install nginx"
            echo ""
            read -p "Press Enter to continue without nginx or Ctrl+C to abort..."
        else
            local nginx_version=$(nginx -v 2>&1)
            log_progress "nginx found: $nginx_version"
        fi
    fi
    
    # Report missing tools
    if [[ ${#missing_tools[@]} -gt 0 ]]; then
        log_error "Missing required tools:"
        for tool in "${missing_tools[@]}"; do
            echo "  - $tool"
        done
        echo ""
        echo "Please install the missing tools and run this script again."
        exit 1
    fi
    
    log_success "All prerequisites satisfied"
}

# Function to compile monitor
compile_monitor() {
    log_step "Compiling monitor Go sources..."
    
    cd "$HOLTER_DIR/monitor"
    
    if [[ ! -f "go.mod" ]]; then
        log_error "monitor/go.mod not found. Are you in the correct directory?"
        exit 1
    fi
    
    log_progress "Cleaning previous builds..."
    go clean
    
    log_progress "Building monitor binary..."
    if go build -o monitor .; then
        log_success "Monitor compiled successfully"
    else
        log_error "Failed to compile monitor"
        exit 1
    fi
    
    cd "$HOLTER_DIR"
}

# Function to compile trode
compile_trode() {
    log_step "Compiling trode Go sources..."
    
    cd "$HOLTER_DIR/trode"
    
    if [[ ! -f "go.mod" ]]; then
        log_error "trode/go.mod not found. Are you in the correct directory?"
        exit 1
    fi
    
    log_progress "Cleaning previous builds..."
    go clean
    
    log_progress "Building trode binary..."
    if go build -o trode .; then
        log_success "Trode compiled successfully"
    else
        log_error "Failed to compile trode"
        exit 1
    fi
    
    cd "$HOLTER_DIR"
}

# Function to reinitialize database
reinitialize_database() {
    if [[ "$SKIP_DB_RESET" == "true" ]]; then
        log_step "Skipping database reinitialization (--skip-db-reset specified)"
        return 0
    fi
    
    log_step "Reinitializing SQLite database..."
    
    # Check if database exists
    if [[ -f "$DB_PATH" ]]; then
        log_progress "Creating backup of existing database..."
        local backup_path="$DB_PATH.backup.$(date +%Y%m%d_%H%M%S)"
        cp "$DB_PATH" "$backup_path"
        log_progress "Backup created: $backup_path"
    fi
    
    # Ensure data directory exists
    mkdir -p "$(dirname "$DB_PATH")"
    
    # Remove existing database
    if [[ -f "$DB_PATH" ]]; then
        log_progress "Removing existing database..."
        rm -f "$DB_PATH"
    fi
    
    # Check if migration script exists
    if [[ ! -f "$MIGRATION_SCRIPT" ]]; then
        log_error "Migration script not found: $MIGRATION_SCRIPT"
        exit 1
    fi
    
    # Create new database with schema
    log_progress "Creating new database with schema..."
    if sqlite3 "$DB_PATH" < "$MIGRATION_SCRIPT"; then
        log_success "Database reinitialized successfully"
    else
        log_error "Failed to reinitialize database"
        exit 1
    fi
    
    # Verify database
    log_progress "Verifying database schema..."
    local table_count=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sqlite_master WHERE type='table';" 2>/dev/null || echo "0")
    log_progress "Created $table_count tables"
}

# Function to build frontend
build_frontend() {
    if [[ "$SKIP_FRONTEND" == "true" ]]; then
        log_step "Skipping frontend build (--skip-frontend specified)"
        return 0
    fi
    
    log_step "Building frontend sources..."
    
    cd "$HOLTER_DIR/frontend"
    
    if [[ ! -f "package.json" ]]; then
        log_error "frontend/package.json not found. Are you in the correct directory?"
        exit 1
    fi
    
    log_progress "Installing npm dependencies..."
    if npm install; then
        log_success "Dependencies installed"
    else
        log_error "Failed to install dependencies"
        exit 1
    fi
    
    log_progress "Building frontend..."
    if npm run build; then
        log_success "Frontend built successfully"
    else
        log_error "Failed to build frontend"
        exit 1
    fi
    
    cd "$HOLTER_DIR"
}

# Function to create nginx configuration
create_nginx_config() {
    log_step "Creating nginx configuration..."
    
    if [[ "$DEV_MODE" == "true" ]]; then
        # Development mode - create local config
        mkdir -p "$(dirname "$NGINX_CONFIG")"
        mkdir -p "$WEB_ROOT"
        
        # Copy frontend build to web root
        log_progress "Copying frontend build to web root..."
        cp -r "$HOLTER_DIR/frontend/dist"/* "$WEB_ROOT/" 2>/dev/null || {
            log_warning "Frontend build not found, creating placeholder"
            echo "<html><body><h1>Holter Frontend</h1><p>Build the frontend first with: npm run build</p></body></html>" > "$WEB_ROOT/index.html"
        }
        
        # Create nginx configuration for development
        log_progress "Creating nginx configuration: $NGINX_CONFIG"
        
        cat << EOF > "$NGINX_CONFIG"
server {
    listen 8080;
    server_name localhost;
    root $WEB_ROOT;
    index index.html;
    
    # Enable gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
    
    # Handle static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Handle API requests (proxy to monitor)
    location /api/ {
        proxy_pass http://localhost:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
    }
    
    # Handle WebSocket connections
    location /ws {
        proxy_pass http://localhost:8081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
    
    # Handle all other requests (SPA routing)
    location / {
        try_files \$uri \$uri/ /index.html;
    }
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
}
EOF
        
        log_success "Nginx configuration created for development"
        
        # Show instructions for using nginx
        echo ""
        echo "To use this nginx configuration:"
        echo "  1. Install nginx: sudo apt-get install nginx"
        echo "  2. Copy config: sudo cp $NGINX_CONFIG /etc/nginx/sites-available/holter"
        echo "  3. Enable site: sudo ln -s /etc/nginx/sites-available/holter /etc/nginx/sites-enabled/"
        echo "  4. Test config: sudo nginx -t"
        echo "  5. Reload nginx: sudo systemctl reload nginx"
        echo ""
        
    else
        # Production mode - configure system nginx
        # Create web root directory
        log_progress "Creating web root directory..."
        sudo mkdir -p "$WEB_ROOT"
        sudo chown -R www-data:www-data "$WEB_ROOT"
        
        # Copy frontend build to web root
        log_progress "Copying frontend build to web root..."
        sudo cp -r "$HOLTER_DIR/frontend/dist"/* "$WEB_ROOT/" 2>/dev/null || {
            log_warning "Frontend build not found, creating placeholder"
            echo "<html><body><h1>Holter Frontend</h1><p>Build the frontend first with: npm run build</p></body></html>" | sudo tee "$WEB_ROOT/index.html" > /dev/null
        }
        
        # Create nginx configuration
        log_progress "Creating nginx configuration: $NGINX_CONFIG"
        
        cat << EOF | sudo tee "$NGINX_CONFIG" > /dev/null
server {
    listen 80;
    server_name localhost;
    root $WEB_ROOT;
    index index.html;
    
    # Enable gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
    
    # Handle static assets
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Handle API requests (proxy to monitor)
    location /api/ {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
        proxy_cache_bypass \$http_upgrade;
    }
    
    # Handle WebSocket connections
    location /ws {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;
    }
    
    # Handle all other requests (SPA routing)
    location / {
        try_files \$uri \$uri/ /index.html;
    }
    
    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
}
EOF
        
        # Enable the site
        log_progress "Enabling nginx site..."
        if [[ -d "/etc/nginx/sites-enabled" ]]; then
            sudo ln -sf "$NGINX_CONFIG" "/etc/nginx/sites-enabled/holter"
        fi
        
        # Test nginx configuration
        log_progress "Testing nginx configuration..."
        if sudo nginx -t; then
            log_success "Nginx configuration is valid"
        else
            log_error "Nginx configuration is invalid"
            exit 1
        fi
        
        # Reload nginx
        log_progress "Reloading nginx..."
        if sudo systemctl reload nginx; then
            log_success "Nginx reloaded successfully"
        else
            log_warning "Failed to reload nginx. You may need to restart it manually:"
            echo "  sudo systemctl restart nginx"
        fi
    fi
}

# Function to start services
start_services() {
    log_step "Starting services..."
    
    # Start monitor if not already running
    log_progress "Starting monitor service..."
    cd "$HOLTER_DIR/monitor"
    
    # Check if monitor is already running
    if pgrep -f "monitor" > /dev/null; then
        log_progress "Monitor is already running"
    else
        # Start monitor in background
        if [[ "$DEV_MODE" == "true" ]]; then
            # Development mode - use port 8081
            nohup ./monitor -port 8081 > monitor.log 2>&1 &
        else
            # Production mode - use port 8080
            nohup ./monitor -port 8080 > monitor.log 2>&1 &
        fi
        local monitor_pid=$!
        echo $monitor_pid > monitor.pid
        log_success "Monitor started with PID: $monitor_pid"
    fi
    
    cd "$HOLTER_DIR"
}

# Function to verify installation
verify_installation() {
    log_step "Verifying installation..."
    
    local verification_passed=true
    
    # Check if binaries exist
    if [[ ! -f "$HOLTER_DIR/monitor/monitor" ]]; then
        log_error "Monitor binary not found"
        verification_passed=false
    else
        log_progress "Monitor binary: ✓"
    fi
    
    if [[ ! -f "$HOLTER_DIR/trode/trode" ]]; then
        log_error "Trode binary not found"
        verification_passed=false
    else
        log_progress "Trode binary: ✓"
    fi
    
    # Check if database exists and has tables
    if [[ ! -f "$DB_PATH" ]]; then
        log_error "Database not found"
        verification_passed=false
    else
        local table_count=$(sqlite3 "$DB_PATH" "SELECT COUNT(*) FROM sqlite_master WHERE type='table';" 2>/dev/null || echo "0")
        if [[ "$table_count" -gt 0 ]]; then
            log_progress "Database with $table_count tables: ✓"
        else
            log_error "Database has no tables"
            verification_passed=false
        fi
    fi
    
    # Check if frontend build exists
    if [[ ! -d "$HOLTER_DIR/frontend/dist" ]]; then
        log_warning "Frontend build not found (skipped or failed)"
    else
        log_progress "Frontend build: ✓"
    fi
    
    # Check if monitor is responding
    sleep 2  # Give monitor time to start
    local monitor_port=$([ "$DEV_MODE" == "true" ] && echo "8081" || echo "8080")
    if curl -s -o /dev/null -w "%{http_code}" "http://localhost:$monitor_port/api/health" 2>/dev/null | grep -q "200"; then
        log_progress "Monitor API responding: ✓"
    else
        log_warning "Monitor API not responding (may need time to start)"
    fi
    
    # Check nginx (production mode only)
    if [[ "$DEV_MODE" == "false" ]]; then
        if command_exists nginx; then
            if curl -s -o /dev/null -w "%{http_code}" http://localhost | grep -q "200\|404"; then
                log_progress "Nginx serving: ✓"
            else
                log_warning "Nginx may not be serving correctly"
            fi
        fi
    fi
    
    if [[ "$verification_passed" == "true" ]]; then
        log_success "Installation verification completed"
    else
        log_error "Installation verification failed"
        exit 1
    fi
}

# Function to show final instructions
show_final_instructions() {
    echo ""
    echo "=========================================="
    if [[ "$DEV_MODE" == "true" ]]; then
        echo "🎉 Holter Build Wizard (Development) Completed Successfully!"
    else
        echo "🎉 Holter Build Wizard (Production) Completed Successfully!"
    fi
    echo "=========================================="
    echo ""
    echo "Your Holter monitoring system is now ready!"
    echo ""
    
    if [[ "$DEV_MODE" == "true" ]]; then
        echo "Access Points (Development Mode):"
        echo "  🔧 Monitor API: http://localhost:8081"
        echo "  📊 WebSocket: ws://localhost:8081/ws"
        echo "  🌐 Frontend: http://localhost:8080 (if nginx is configured)"
        echo ""
        echo "Service Management:"
        echo "  📁 Monitor logs: $HOLTER_DIR/monitor/monitor.log"
        echo "  🖥️  Monitor PID: $HOLTER_DIR/monitor/monitor.pid"
        echo "  🌐 Nginx config: $NGINX_CONFIG"
        echo "  📂 Web root: $WEB_ROOT"
    else
        echo "Access Points (Production Mode):"
        echo "  🌐 Frontend: http://localhost"
        echo "  🔧 Monitor API: http://localhost:8080"
        echo "  📊 WebSocket: ws://localhost:8080/ws"
        echo ""
        echo "Service Management:"
        echo "  📁 Monitor logs: $HOLTER_DIR/monitor/monitor.log"
        echo "  🖥️  Monitor PID: $HOLTER_DIR/monitor/monitor.pid"
        echo "  🌐 Nginx config: $NGINX_CONFIG"
        echo "  📂 Web root: $WEB_ROOT"
    fi
    
    echo ""
    echo "Next Steps:"
    echo "  1. Add monitoring nodes through the web interface"
    echo "  2. Deploy trodes to remote servers"
    echo "  3. Configure monitoring thresholds"
    echo ""
    echo "For more information, see:"
    echo "  📖 DEPLOYMENT_GUIDE.md"
    echo "  📖 BOOTSTRAP_SYSTEM.md"
    echo ""
    echo "Log file: $LOG_FILE"
    echo ""
}

# Main execution
main() {
    echo "=========================================="
    if [[ "$DEV_MODE" == "true" ]]; then
        echo "🚀 Holter Build Wizard (Development Mode)"
    else
        echo "🚀 Holter Build Wizard (Production Mode)"
    fi
    echo "=========================================="
    echo ""
    echo "This wizard will build and configure your Holter monitoring system."
    echo "Log file: $LOG_FILE"
    echo ""
    
    # Check if we're in the right directory (look for go.work file)
    if [[ ! -f "$HOLTER_DIR/go.work" ]]; then
        log_error "go.work file not found. Please run from the holter project root."
        exit 1
    fi
    
    # Run all steps
    check_prerequisites
    compile_monitor
    compile_trode
    reinitialize_database
    build_frontend
    create_nginx_config
    start_services
    verify_installation
    
    # Show final instructions
    show_final_instructions
}

# Run main function
main "$@" 